package br.usp.icmc.biomac.shared;

import com.google.gwt.core.client.Duration;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;

/**
 * Logger for ePad Client. Will try to log events to the java-script console, GWT logger,
 * and keep a history of messages.
 *
 * @author amsnyder
 */
public class EPadLogger {
    private static EPadLogger ourInstance = new EPadLogger();

    MessageHistory history;
    MessageHistory debugHistory;
    Duration duration;

    boolean useGwtLogger = true;
    boolean useConsoleLogger = true;
    boolean useWebSocketLogger = false;

    boolean showDebugMessage = true;

    public static EPadLogger getLogger() {
        return ourInstance;
    }

    private EPadLogger() {
        try{
            history = new MessageHistory(50);
            debugHistory  = new MessageHistory(50);
            duration = new Duration();
        }catch(Exception e){
            Window.alert("EPadLogger had: "+e.getMessage());
        }
    }

    /**
     *
     * @param show boolean
     */
    public void showDebugMessages(boolean show){
        showDebugMessage = show;
    }

    /**
     * Log a debug message.
     * @param message
     */
    public void debug(String message){
        createMessage(MessageLevel.DEBUG,message);
    }

    /**
     * Log an info message
     * @param message
     */
    public void info(String message){
        createMessage(MessageLevel.INFO,message);
    }

    /**
     * Log a warning
     * @param message
     */
    public void warn(String message){
        createMessage(MessageLevel.WARN,message);
    }

    /**
     * Log an error
     * @param message
     */
    public void error(String message){
        createMessage(MessageLevel.SEVERE,message);
    }

    /**
     * Show an alert box and then log the message as an error.
     * @param message
     */
    public void alert(String message){
        Window.alert(message);
        error(message);
    }

    /**
     * Show an alert box for a debug message.
     * @param message
     */
    public void alertDebug(String message){
        Window.alert(message);
        debug(message);
    }

    private void createMessage(MessageLevel level, String message){
        String step="init";
        try{
            step="time";
            int elapsedMs = duration.elapsedMillis();


            step="message";
            Message m = new Message(elapsedMs, level, message);
            step="level";
            if(level==MessageLevel.DEBUG){
                if(debugHistory!=null){
                    step="add-debug";
                    debugHistory.add(m);
                }
            }
            if(history!=null){
                step="add";
                history.add(m);
            }
            step="send";
            sendToLoggers(m);
        }catch(Exception e){
            Window.alert("EPadLogger.createMessage @step("+step+") had: "+e.getMessage());
        }
    }

    /***
     * We have a message send it to the different types of client side loggers.
     * @param m
     */
    private void sendToLoggers(Message m){

        String step="init";
        try{
            step="check null";
            if(m==null){ return; }
            step="isDebug";
            if(!showDebugMessage && m.isDebug() ){
                    //don't show a debug message
                    return;
            }

            step="gwt-logger";
            if(useGwtLogger){
                GWT.log(m.toString());
            }

            step="console-logger";
            if(useConsoleLogger){
                log(m.toString());
            }
        }catch(Exception e){
            Window.alert("..."+e.getMessage() );
            throw new IllegalStateException("EPadLogger.sendToLoggers @"+step,e);
        }
    }

    /**
     * Send the messages to the javascript console logger.
     * @param message
     */
    private static native void log(Object message) /*-{
        if (console) {
            console.log(message);
        }
    }-*/;

}
